mybatis 插件使用及原理
[TOC]
一. 插件使用
1. 接口说明
- intercept方法:将直接覆盖你所拦截对象原有的方法。参数Invocation中的- proceed可以调用原来的方法
- plugin方法:var1为被拦截对象,该方法为被拦截的对象生成一个代理对象
- setProperties方法:允许在plugin元素中配置所需参数,在插件初始化时,被调用一次,把插件对象存到配置中,方便以后取出
2. 接口示例
2.1. 插件接口
1. 说明
- 创建该接口的类需要加上对象的注解@Intercepts @Signature,标明拦截的类及方法
- mybatis提供Plugin工具类,是InvocationHandler接口的实现,该类的wrap方法可用于生成代理对象
2. Plugin.wrap方法: 传入参数为当前要被代理的对象,及拦截器。具体的代理内容为其invoke方法执行的东西
这里判断所执行的方法是否为拦截方法,是则执行拦截器中的方法,不是则不拦截,调用其本身
2.2. 相关配置
当运行的时候,有调用到该方法即可以使用了
二. 插件原理
1. 插件初始化
创建Configuration对象时,调用pluginElement方法读取plugin标签内容
源码图
说明
- 通过反射生成插件实例,并调用了setProperties
- 使用List保存生成插件实例
这里setProperties方法,使用了模版方法设计模式
2. 拦截范围
提供的拦截范围为: 四大对象
1. 如何拦截: 以Executor为例,其余对象均相同
这里使用到了责任链模式,MyBatis的责任链由Configuration中的InterceptorChain对象去定义的。这里Executor对象不断被链中的插件进行代理(可以代理很多层)
InterceptorChain类十分简单,可以去看看源码,这里就不贴了
三. 插件的常用工具类
没具体看,有个印象即可
MetaObject
四大对象提供给我们的public设置参数的方法很少,难以通过自身得到相关的属性信息,我们可以通过MetaObject这个工具类来读取或修改这些重要对象的属性
三个常用方法:
- SystemMetaObejct.forObject(Object obj),用于包装对象
(forObject 并不是太清楚) - Object getValue(String name),用于获取对象属性值
- void setValue(String name,Object value),用于修改对象属性值
四. 插件总结